package com.tcoding.client.components.extend;

import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import com.tcoding.client.event.CustomerEvent;
import com.tcoding.client.utils.SvgGraphicUtil;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import org.apache.poi.ss.formula.functions.T;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

/**
 * @author 唐全成
 * @Date: 2022/9/8 15:56
 * @description
 **/
public class JFXDateTimeCalendar extends VBox {


    public List<Button> dayList;
    public Calendar calendar;
    public Calendar tmpCalendar;
    public SimpleDateFormat sdf;
    public VBox root;
    public VBox root1;
    public FlowPane flowPane;
    public FlowPane flow;
    public Label labelYear;
    public Label labelMouth;
    public String strYear;
    public String strYearMouth;
    public String strYearMouthDay;
    public Label labelSelected;

    /**
     * Creates a VBox layout with spacing = 0 and alignment at TOP_LEFT.
     */
    public JFXDateTimeCalendar(EventHandler<CustomerEvent<T>> okHandler,EventHandler<CustomerEvent<T>> cancelHandler) {
        root = new VBox();
        root.setMinSize(310,250);
        root.setMaxSize(310,400);
        root1 = new VBox();
        root1.setAlignment(Pos.TOP_CENTER);
        root1.getChildren().add(root);
        dayList = new ArrayList<Button>();
        /*
         * 星期
         * */
        flowPane = new FlowPane();
        flowPane.setStyle("-fx-alignment: center;-fx-pref-height: 50px;");
        flowPane.setVgap(10);
        flowPane.setHgap(33);
        flowPane.setPrefWrapLength(310);
        flowPane.getChildren().add(new Label("一"));
        flowPane.getChildren().add(new Label("二"));
        flowPane.getChildren().add(new Label("三"));
        flowPane.getChildren().add(new Label("四"));
        flowPane.getChildren().add(new Label("五"));
        flowPane.getChildren().add(new Label("六"));
        flowPane.getChildren().add(new Label("日"));
        /*
         * 当月日期
         * */
        flow = new FlowPane();
        flow.setVgap(8);
        flow.setHgap(8);
        flow.setPrefWrapLength(310);
        /*
         * 生成一个Calendar，设置为运行程序的时间
         * */
        calendar = Calendar.getInstance();
        /*
         * 生成日期部分
         * */
        upDataCalendar();

        Separator sp1 = new Separator();
        Separator sp2 = new Separator();


        /**
         * 生成和月的左右选择
         */
        HBox hBox = new HBox(10);
        hBox.setAlignment(Pos.CENTER);


        labelYear = new Label(calendar.get(Calendar.YEAR)+"");
        Label label1 = new Label("年");
        labelMouth = new Label(""+(calendar.get(Calendar.MONTH)+1));
        Label label2 = new Label("月");


        Button btnYearLeft = new Button("<<");
        btnPress(btnYearLeft);
        Button btnYearRight = new Button(">>");
        btnPress(btnYearRight);
        btnYearLeft.setBackground(Background.EMPTY);
        btnYearRight.setBackground(Background.EMPTY);
        Button btnMouthLeft = new Button("<");
        btnMouthLeft.setBackground(Background.EMPTY);
        btnPress(btnMouthLeft);
        Button btnMouthRight = new Button(">");
        btnMouthRight.setBackground(Background.EMPTY);
        btnPress(btnMouthRight);


        hBox.getChildren().addAll(btnYearLeft,btnMouthLeft,labelYear,label1,labelMouth,label2,btnMouthRight,btnYearRight);


        /**
         * 生成时分秒选择框，默认取当前时间
         */
        HBox hBoxHMS = new HBox(4);
        hBoxHMS.setStyle("-fx-pref-height: 50px;-fx-text-fill: #fff");
        JFXComboBox<Integer> hour = new JFXComboBox<Integer>();
        for (int i = 0;i < 24;i++){
            hour.getItems().add(i);
        }
        hour.getSelectionModel().select(calendar.get(Calendar.HOUR_OF_DAY));

        Label labelHour = new Label("时");

        JFXComboBox<Integer> minute = new JFXComboBox<Integer>();
        for (int i = 0;i < 60;i++){
            minute.getItems().add(i);
        }
        minute.getSelectionModel().select(calendar.get(Calendar.MINUTE));
        Label labelMinute = new Label("分");
        JFXComboBox<Integer> second = new JFXComboBox<Integer>();
        for (int i = 0;i < 60;i++){
            second.getItems().add(i);
        }
        second.getSelectionModel().select(calendar.get(Calendar.SECOND));

        Label labelSecond = new Label("秒");


        hBoxHMS.setAlignment(Pos.CENTER);
        hBoxHMS.getChildren().addAll(hour,labelHour,minute,labelMinute,second,labelSecond);


        /**
         *
         * 记录当前已选择时间
         */
        HBox hBoxSelect = new HBox(5);
        hBoxSelect.setAlignment(Pos.CENTER);
        Label labelSelect = new Label("当前选择时间：");
        labelSelected = new Label();
        hBoxSelect.getChildren().addAll(labelSelected);
        /**
         *
         * 取消和确认按钮，点击确认按钮获取 年-月-日 时:分:秒
         */
        HBox hBoxOKCancel = new HBox();
        hBoxOKCancel.setAlignment(Pos.CENTER);
        JFXButton btnOK = new JFXButton("确认");
        btnOK.setMinSize(175,40);
        btnOK.setMaxSize(175,40);
        btnOK.setButtonType(JFXButton.ButtonType.RAISED);
        btnOK.setOnAction(e-> {
            String result=null;
            if(tmpCalendar!=null){
                result = strYear+"-"+getTimeStr((Integer.parseInt(strYearMouth)+1))+"-"+strYearMouthDay+" "+strValue(Integer.valueOf(hour.getValue()))+":"+strValue(Integer.valueOf(minute.getValue()))+":"+strValue(Integer.valueOf(second.getValue()));
            }

            String finalResult = result;
            okHandler.handle(new CustomerEvent<>(e, new HashMap<String, Object>(4) {{
                put("data", finalResult);
            }}));
        });

        JFXButton btnCancel = new JFXButton("取消");
        btnCancel.setButtonType(JFXButton.ButtonType.RAISED);
        btnCancel.setMinSize(175,40);
        btnCancel.setMaxSize(175,40);
        btnCancel.setOnAction(event -> {
            cancelHandler.handle(new CustomerEvent<>(event,new HashMap<>()));
        });
        hBoxOKCancel.getChildren().addAll(btnCancel,btnOK);
        this.setPadding(new Insets(20,0,0,0));
        this.setStyle("-fx-background-color: #fff;-fx-font-size: 12px");
        this.getChildren().addAll(hBox,root1,sp1,hBoxHMS,sp2,hBoxSelect,hBoxOKCancel);
    }

    private String getTimeStr(Integer num){

        if(num<10){
            return "0"+num;
        }else {
            return String.valueOf(num);
        }

    }


    public String strValue(int i){
        String res;
        if (i <10){
            res="0"+i;
        }else {
            res = i+"";
        }

        return res;
    }


    /**
     *
     * 设置年月左右选择按钮被按下时和弹起时的颜色
     * @param btn  年月左右选择按钮Button
     */
    public void btnMouthPress(Button btn){
        btn.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                btn.setStyle("-fx-text-fill: black;-fx-background-color: #FFD306;");
            }
        });
        btn.setOnMouseReleased(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                btn.setStyle("-fx-background-color: transparent;");
            }
        });
    }

    public void btnYearPress(Button btn){
        btn.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                btn.setStyle("-fx-text-fill: black;-fx-background-color:#ff8080;");
            }
        });
        btn.setOnMouseReleased(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                btn.setStyle("-fx-background-color: transparent;");
            }
        });
    }


    /**
     * 给年月左右选择按钮绑定事件
     * @param btn  年月左右选择按钮Button
     */
    public void btnPress(Button btn){
        if (btn.getText().trim().equals("<")){
            btn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    calendar.add(Calendar.MONTH,-1);
                    upDataLab(labelYear,labelMouth);
                    upDataCalendar();
                }
            });
            btnMouthPress(btn);
        }else if (btn.getText().trim().equals(">")){
            btn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    calendar.add(Calendar.MONTH,1);
                    upDataLab(labelYear,labelMouth);
                    upDataCalendar();
                }
            });
            btnMouthPress(btn);
        }else if (btn.getText().trim().equals("<<")){
            btn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    calendar.add(Calendar.YEAR,-1);
                    upDataLab(labelYear,labelMouth);
                    upDataCalendar();
                }
            });
            btnYearPress(btn);
        }else if (btn.getText().trim().equals(">>")){
            btn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    calendar.add(Calendar.YEAR,1);
                    upDataLab(labelYear,labelMouth);
                    upDataCalendar();
                }
            });
            btnYearPress(btn);
        }
    }


    /**
     * 设置上月和下月在本月显示的日期样式，并设置为不可点击
     * @param btn  日期按钮Button
     */
    public void setDisable(Button btn){
        btn.setDisable(true);
        btn.setStyle("-fx-text-fill: black;-fx-background-color: transparent;");
    }


    /**
     * 设置本月日期的点击事件和样式，其中点击时间后，自动记录时间
     * @param btn  日期按钮Button
     */
    public void setAble(Button btn){
        btn.setStyle("-fx-text-fill: black;-fx-background-color: #fff;");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                dayList.forEach(e->{e.setStyle("-fx-text-fill: black;-fx-background-color: #fff;");});
                btn.setStyle("-fx-text-fill: white;-fx-background-color: #5b8cff;");

                strYear = calendar.get(Calendar.YEAR)+"";
                strYearMouth = ""+calendar.get(Calendar.MONTH);
                strYearMouthDay = btn.getText();
                tmpCalendar = Calendar.getInstance();
                tmpCalendar.set(Integer.valueOf(strYear),Integer.valueOf(strYearMouth),Integer.valueOf(strYearMouthDay));
                //System.out.println(tmpCalendar.getTime());
                labelSelected.setText(tmpCalendar.get(Calendar.YEAR)+"年"+(tmpCalendar.get(Calendar.MONTH)+1)+"月"+tmpCalendar.get(Calendar.DAY_OF_MONTH)+"日");
            }
        });
    }

    /**
     * 用于更新年月展示
     * @param lbY
     * @param lbM
     */
    public void upDataLab(Label lbY,Label lbM){
        lbM.setText(""+(calendar.get(Calendar.MONTH)+1));
        lbY.setText(calendar.get(Calendar.YEAR)+"");
    }


    /**
     * 更新日期部分的数据
     */
    public void upDataCalendar(){
        /*
         * 获取当月天数
         * calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
         * */

        /**
         * 获取当前年月，用于判断是否为已选时间所在月份
         */
        String tmpStr = calendar.get(Calendar.YEAR)+","+calendar.get(Calendar.MONTH);


        if (tmpStr.equals(strYear+","+strYearMouth)){
            /**
             * 判断结果为当前年月是已选时间所在月份，自动为已选日期改为选中样式
             */
            dayList.clear();
            flow.getChildren().clear();
            int mouthDays = tmpCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            tmpCalendar.set(tmpCalendar.get(Calendar.YEAR),tmpCalendar.get(Calendar.MONTH),mouthDays,tmpCalendar.get(Calendar.HOUR_OF_DAY),tmpCalendar.get(Calendar.MINUTE),tmpCalendar.get(Calendar.SECOND));
            int weekMouthLastDay = tmpCalendar.get(Calendar.DAY_OF_WEEK);
            tmpCalendar.set(tmpCalendar.get(Calendar.YEAR),tmpCalendar.get(Calendar.MONTH),1,tmpCalendar.get(Calendar.HOUR_OF_DAY),tmpCalendar.get(Calendar.MINUTE),tmpCalendar.get(Calendar.SECOND));
            int weekMouthFirstDay = tmpCalendar.get(Calendar.DAY_OF_WEEK);

            tmpCalendar.add(Calendar.MONTH,-1);
            int lastMouthDays = tmpCalendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            tmpCalendar.add(Calendar.MONTH,1);

            //System.out.println("本月天数："+mouthDays+"   上月天数"+lastMouthDays);



            if (weekMouthFirstDay == 1){
                //System.out.println("本月第一天是周日，前面有6天");
                for (int i = lastMouthDays-5;i<=lastMouthDays;i++){
                    //dayList.add(i);
                    Button btn = new Button(strValue(i));
                    setDisable(btn);
                    flow.getChildren().add(btn);
                }
                for (int i = 1;i<=mouthDays;i++){
                    Button btn = new Button(strValue(i));
                    dayList.add(btn);
                    setAble(btn);
                    flow.getChildren().add(btn);
                }
            }else if (weekMouthFirstDay == 2){
                //System.out.println("本月第一天是周一，前面没有");
                for (int i = 1;i<=mouthDays;i++){
                    Button btn = new Button(strValue(i));
                    dayList.add(btn);
                    setAble(btn);
                    if (strYearMouthDay.equals(strValue(i))){
                        btn.setStyle("-fx-text-fill: white;-fx-background-color: #5b8cff;");
                    }
                    flow.getChildren().add(btn);
                }
            }else{
                //System.out.println("本月第一天不是周日，也不是周一");
                for (int i = lastMouthDays-weekMouthFirstDay+3;i<=lastMouthDays;i++){
                    //dayList.add(i);
                    Button btn = new Button(strValue(i));
                    setDisable(btn);
                    flow.getChildren().add(btn);
                }
                for (int i = 1;i<=mouthDays;i++){
                    Button btn = new Button(strValue(i));
                    dayList.add(btn);
                    setAble(btn);
                    if (strYearMouthDay.equals(strValue(i))){
                        btn.setStyle("-fx-text-fill: white;-fx-background-color: #5b8cff;");
                    }
                    flow.getChildren().add(btn);
                }
            }

            if (weekMouthLastDay != 1){
                for (int i = 1;i<=8-weekMouthLastDay;i++){
                    //dayList.add(i);
                    Button btn = new Button(strValue(i));
                    setDisable(btn);
                    flow.getChildren().add(btn);
                }
            }


            root.getChildren().clear();
            root.getChildren().addAll(flowPane,flow);
            root1.getChildren().clear();
            root1.getChildren().add(root);
        }else{

            dayList.clear();
            flow.getChildren().clear();
            int mouthDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),mouthDays,calendar.get(Calendar.HOUR_OF_DAY),calendar.get(Calendar.MINUTE),calendar.get(Calendar.SECOND));
            int weekMouthLastDay = calendar.get(Calendar.DAY_OF_WEEK);
            calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1,calendar.get(Calendar.HOUR_OF_DAY),calendar.get(Calendar.MINUTE),calendar.get(Calendar.SECOND));
            int weekMouthFirstDay = calendar.get(Calendar.DAY_OF_WEEK);

            calendar.add(Calendar.MONTH,-1);
            int lastMouthDays = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            calendar.add(Calendar.MONTH,1);

            //System.out.println("本月天数："+mouthDays+"   上月天数"+lastMouthDays);



            if (weekMouthFirstDay == 1){
                //System.out.println("本月第一天是周日，前面有6天");
                for (int i = lastMouthDays-5;i<=lastMouthDays;i++){
                    //dayList.add(i);
                    Button btn = new Button(strValue(i));
                    setDisable(btn);
                    flow.getChildren().add(btn);
                }
                for (int i = 1;i<=mouthDays;i++){
                    Button btn = new Button(strValue(i));
                    dayList.add(btn);
                    setAble(btn);
                    flow.getChildren().add(btn);
                }
            }else if (weekMouthFirstDay == 2){
                //System.out.println("本月第一天是周一，前面没有");
                for (int i = 1;i<=mouthDays;i++){
                    Button btn = new Button(strValue(i));
                    dayList.add(btn);
                    setAble(btn);
                    flow.getChildren().add(btn);
                }
            }else{
                //System.out.println("本月第一天不是周日，也不是周一");
                for (int i = lastMouthDays-weekMouthFirstDay+3;i<=lastMouthDays;i++){
                    //dayList.add(i);
                    Button btn = new Button(strValue(i));
                    setDisable(btn);
                    flow.getChildren().add(btn);
                }
                for (int i = 1;i<=mouthDays;i++){
                    Button btn = new Button(strValue(i));
                    dayList.add(btn);
                    setAble(btn);
                    flow.getChildren().add(btn);
                }
            }

            if (weekMouthLastDay != 1){
                for (int i = 1;i<=8-weekMouthLastDay;i++){
                    //dayList.add(i);
                    Button btn = new Button(strValue(i));
                    setDisable(btn);
                    flow.getChildren().add(btn);
                }
            }


            root.getChildren().clear();
            root.getChildren().addAll(flowPane,flow);
            root1.getChildren().clear();
            root1.getChildren().add(root);
        }


    }
}
